﻿using System;
using System.Linq;
using System.Threading;
using AccelerateSensor.Handler;
using AccelerateSensor.SuperSocket.Tools;
using SuperSocket.SocketBase;

namespace AccelerateSensor.SuperSocket.Server
{
    public class MySession : AppSession<MySession, MyRequestInfo>, ISensorDataHandlerObserver
    {
        public new MyServer AppServer => (MyServer) base.AppServer;
        public string Id => $"{RemoteEndPoint.Address}.{RemoteEndPoint.Port}";
        public bool Timeout => (DateTime.Now - _updateTime).TotalSeconds > 30;

        private long _packageNumber;
        private DateTime _updateTime;

        private readonly SensorDataHandler _sensorDataHandler;

        public MySession()
        {
            _sensorDataHandler = new SensorDataHandler(this);
        }

        protected override void OnSessionStarted()
        {
            //Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - " +
            //                  $"New Session Connected: {RemoteEndPoint.Address} " +
            //                  $"@ {RemoteEndPoint.Port}.");
            AppServer.RegisterSession(this);
            _sensorDataHandler.Start();
            //Send("Welcome to SuperSocket Telnet Server.");
            _updateTime = DateTime.Now;
            LogHelper.AddLog($"New Session Connected: {RemoteEndPoint.Address}.{RemoteEndPoint.Port}");
        }

        protected override void HandleUnknownRequest(MyRequestInfo requestInfo)
        {
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - "
                              + $"Unknown request {requestInfo.Key}.");
            //Send("Unknown request.");
            LogHelper.AddLog($"Unknown request {requestInfo.HexString}.");
        }

        protected override void HandleException(Exception e)
        {
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - "
                              + $"Application error: {e.Message}.");
            //Send($"Application error: {e.Message}.");
            LogHelper.AddLog($"Application error: {e.Message}.");
        }

        protected override void OnSessionClosed(CloseReason reason)
        {
            //Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - " +
            //                  $"Session {RemoteEndPoint.Address} @ {RemoteEndPoint.Port} " +
            //                  $"Closed: {reason}.");
            LogHelper.AddLog($"Session {RemoteEndPoint.Address}.{RemoteEndPoint.Port} Closed: {reason}.");
            AppServer.UnRegisterSession(Id);
            _sensorDataHandler.Stop();
            base.OnSessionClosed(reason);
        }

        public void ReceiveSensorData(string data)
        {
            AddPackageCount();
            LogHelper.AddLog($"Receive sensor data: {data}");
            //Console.WriteLine($"Receive sensor data: {data}");
            _sensorDataHandler.AddMessage(data);
        }

        #region 统计数据

        private void AddPackageCount()
        {
            Interlocked.Increment(ref _packageNumber);
        }

        public void ResetPackageCount()
        {
            Interlocked.Exchange(ref _packageNumber, 0);
        }

        public long PackageCount => Interlocked.Read(ref _packageNumber);

        #endregion

        public void ReceiveHeartbeat()
        {
            _updateTime = DateTime.Now;

            var heartbeatLenBuffer = MessageHelper.GetHeartbeatLenBuffer();
            Send(heartbeatLenBuffer, 0, heartbeatLenBuffer.Length);

            var heartbeatBuffer = MessageHelper.GetHeartbeatBuffer();
            Send(heartbeatBuffer, 0, heartbeatBuffer.Length);

            LogHelper.AddLog("========== Send heartbeat back to client ==========");
            Console.WriteLine("========== Send heartbeat back to client ==========");
        }
    }
}
